package com.hzz.service.dsync;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzz.dao.dsync.IDSyncDao;
import com.hzz.entity.dsync.DSync;
import com.hzz.framework.Response;
import com.hzz.framework.dto.IDto;
import com.hzz.framework.fileServer.config.FileServerProperties;
import com.hzz.framework.util.CommonConstant;
import com.hzz.framework.util.DateUtil;
import com.hzz.framework.util.IdUtil;
import com.hzz.framework.util.StrUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@Data
public class BaseDSync {
    @Value("${dsync.enabled:true}")
    protected Boolean syncEnabled;

    @Value("${dsync.eySubmit.patrol-task-record}")
    protected String patrolTaskRecord;
    @Value("${dsync.eySubmit.patrol-task-event}")
    protected String patrolTaskEvent;

    @Value("${dsync.accounts.header}")
    protected String accountsHeader;
    @Value("${dsync.accounts.server}")
    protected String accountsServer;
    @Value("${dsync.accounts.auth-secret-key}")
    protected String accountsAuthSecretKey;
    @Value("${dsync.accounts.auth-id}")
    protected String accountsAuthId;
    @Value("${dsync.accounts.auth-key}")
    protected String accountsAuthKey;

    private static final String AUTH_EXPIRES = "Expires";
    private static final String AUTH_ISSUEDATE = "IssueDate";
    private static final String AUTH_TOKEN = "Token";

    protected static JSONObject authJsonObject;
    @Autowired
    FileServerProperties fileServerProperties;

    @Autowired
    IDSyncDao dsyncDao;
    protected final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(2 * 60 * 1000, TimeUnit.MILLISECONDS)
            .readTimeout(5 * 60 * 1000, TimeUnit.MILLISECONDS)
            .writeTimeout(5 * 60 * 1000, TimeUnit.MILLISECONDS)
            .build();
    private final MediaType FROM_DATA = MediaType.parse("multipart/form-data");

    protected boolean isSyncEnabled() {
        try {
            if (!syncEnabled) {
                log.error("已停用同步功能");
                return false;
            }
        } catch (Exception e) {
            log.error("isSyncEnabled ..", e);
            return false;
        }
        return true;
    }

    protected boolean isSyncEnabled(String nextId, String type, IDto entity) {
        try {
            if (!syncEnabled) {
                log.error("已停用同步功能");
                return false;
            }
        } catch (Exception e) {
            log.error("isSyncEnabled ..", e);
            return false;
        }
//        try {
//            DSync dSync = new DSync();
//            dSync.setId(nextId);
//            dSync.setType(type);
//            dSync.setDjson(JSON.toJSONString(entity));
//            dSync.setState(0);
//            dsyncDao.insert(dSync);
//        } catch (Exception e) {
//            log.error("记录同步日志,异常!", e);
//        }
        return true;
    }

    public boolean updateState(String nextId, Response result) {
        try {
            DSync dSync = new DSync();
            dSync.setId(nextId);
            if (result.code == CommonConstant.TASK_STATUS_基础数据_成功拉取) {
                log.info("同步成功,删除重试日志!");
                dsyncDao.deleteByPrimaryKey(dSync);
            } else {
                log.info("同步失败!" + JSON.toJSONString(result));
                dSync.setState(2);
                dSync.setResult(JSON.toJSONString(result));
                dsyncDao.updateStateById(dSync);
            }
        } catch (Exception e) {
            log.error("更新同步日志,异常!", e);
        }
        return true;
    }

    public String getAuthToken() throws Exception {
        log.debug("getAuthToken...");
        if (authJsonObject == null || (authJsonObject.getLongValue(AUTH_EXPIRES) - DateUtil.getDistinceMinute(authJsonObject.getString(AUTH_ISSUEDATE), DateUtil.getDateTimeStr(new Date()))) < 30) {
            log.info("new authToken...");
            try {
                Map<String, String> stringHashMap = new HashMap<>();
                stringHashMap.put("AuthSecretKey", accountsAuthSecretKey);
                stringHashMap.put("AuthId", accountsAuthId);
                stringHashMap.put("AuthKey", accountsAuthKey);

                RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), JSONObject.toJSONString(stringHashMap));
                Request request = new Request.Builder()
                        .post(requestBody)
                        .url(accountsServer)
                        .build();
                ResponseBody result = client.newCall(request).execute().body();
                String resultStr = result.string();
                log.info("登录反馈 getAuthToken:{}", resultStr);
                Response response = JSONObject.parseObject(resultStr, Response.class);
                if (response != null && response.code == CommonConstant.TASK_STATUS_基础数据_成功拉取) {
                    authJsonObject = (JSONObject) response.data;
                    authJsonObject.put(AUTH_ISSUEDATE, DateUtil.getDateTimeStr(new Date()));
                    return authJsonObject.getString(AUTH_TOKEN);
                } else {
                    throw new RuntimeException(resultStr);
                }
            } catch (Exception e) {
                log.error("获取上级接口授权信息,异常A", e);
                throw new RuntimeException("获取上级接口授权信息,异常B", e);
            }
        } else {
            log.info("his authToken...");
            return authJsonObject.getString(AUTH_TOKEN);
        }
    }

    public Response syncPost(String nx, String djson, String syncUrl) throws Exception {
        log.info("syncPost...");
        Response response;
        String resultStr = "ERROR";
        long sTime = System.currentTimeMillis();
        long eTime = 0;
        try {
            //        log.info("djson:{}", djson);
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), djson);
            Request request = new Request.Builder()
                    .post(requestBody)
                    .addHeader(accountsHeader, getAuthToken())
                    .url(syncUrl)
                    .build();
            ResponseBody result = client.newCall(request).execute().body();
            resultStr = result.string();
            eTime = System.currentTimeMillis();
            log.info("访问接口:" + syncUrl + ",耗时:" + (eTime - sTime));
            response = JSONObject.parseObject(resultStr, Response.class);
            if (response != null && response.code == 650) {
                authJsonObject = null;
            }
            if (response.code != 200) {
                // log.error("访问接口:" + syncUrl + ",耗时:" + (eTime - sTime) + ",result:" + resultStr);
                throw new RuntimeException(resultStr);
            }
        } catch (Exception e) {
            log.error("访问接口:" + syncUrl + ",resultStr:" + resultStr, e);
            response = Response.error(500, e.getMessage());
            writerFile("post-" + nx, resultStr);
        }
        return response;
    }

    public Response syncGet(String nx, String syncUrl) throws Exception {
        log.info("syncGet...");
        Response response;
        String resultStr = "ERROR";
        long sTime = System.currentTimeMillis();
        long eTime = 0;
        try {
            Request request = new Request.Builder()
                    .url(syncUrl)
                    .addHeader(accountsHeader, getAuthToken())
                    .build();
            ResponseBody result = client.newCall(request).execute().body();
            resultStr = result.string();
            eTime = System.currentTimeMillis();
            log.info("访问接口:" + syncUrl + ",耗时:" + (eTime - sTime));
            response = JSONObject.parseObject(resultStr, Response.class);
            if (response != null && response.code == 650) {
                authJsonObject = null;
            }
            if (response.code != 200) {
                // log.error("访问接口:" + syncUrl + ",耗时:" + (eTime - sTime) + ",result:" + resultStr);
                throw new RuntimeException(resultStr);
            }
        } catch (Exception e) {
            log.error("访问接口:" + syncUrl + ",resultStr:" + resultStr, e);
            response = Response.error(500, e.getMessage());
            writerFile("get-" + nx, resultStr);
        }
        return response;
    }

    void writerFile(String nx, String resultStr) {
        try {
            PrintWriter pw = new PrintWriter(fileServerProperties.getRootFolder() + nx + ".json", "utf-8");
            pw.write(resultStr);
            pw.flush();
            pw.close();
        } catch (Exception e) {
            log.error("", e);
        }
    }


    public void logDSyncAdd(String type, String apiUrl, Response response) {
        logDSyncAdd(type, apiUrl, null, response);
    }

    public void logDSyncAdd(String type, String apiUrl, String djson, Response response) {
        try {
            if (response == null || response.code == CommonConstant.TASK_STATUS_基础数据_成功拉取) {
                return;
            }
            DSync dSync = new DSync();
            dSync.setId(StrUtil.asString(IdUtil.nextId()));
            dSync.setType(type);
            dSync.setApiurl(apiUrl);
            dSync.setDjson(djson);
            dSync.setResult(JSON.toJSONString(response));
            dSync.setState(2);
            if (dsyncDao.isDataExistByDJson(dSync) > 0) {
                dsyncDao.updateStateByDJson(dSync);
            } else {
                dsyncDao.insert(dSync);
            }
        } catch (Exception e) {
            log.error("记录同步异常日志!", e);
        }
    }

    public void logDSyncDel(String nextId) {
        try {
            DSync dSync = new DSync();
            dSync.setId(nextId);
            dsyncDao.deleteByPrimaryKey(dSync);
        } catch (Exception e) {
            log.error("删除同步异常日志!", e);
        }
    }

    public static void main(String[] args) throws Exception {
        String dataJson = "{" +
                "\"accompanyPeople\": \"韩伟\"," +
                "\"gmCode\": \"13890578881\"," +
                "\"guid\": \"900200370070884352\"," +
                "\"objType\": \"111\"," +
                "\"pac\": \"511025\"," +
                "\"patrolRiverEndDate\": \"2021-04-15 17:31:00\"," +
                "\"patrolRiverMeetingInfo\": \"巡河\"," +
                "\"patrolRiverStartDate\": \"2021-04-15 17:29:00\"," +
                "\"river\": \"太阳河板栗桠镇段\"," +
                "\"riverBasinName\": \"太阳河板栗桠镇段\"," +
                "\"riverChief\": \"韩伟\"," +
                "\"riverSection\": \"太阳河板栗桠镇段\"," +
                "\"riverbasin\": \"04\"," +
                "\"riverchiefLevel\": \"03\"," +
                "\"sid\": \"25725\"," +
                "\"toolClassSign\": \"25725\"," +
                "\"toolObjectId\": \"25725\"," +
                "\"tourLen\": 0.0," +
                "\"trackPoints\": [{\"lat\":30.678130910071697,\"lng\":104.0197184952171}]" +
                "}";
        // {\"guid\":\"dd51099ff9204e828b95940ee58238fa\"," +
        // "\"gmcode\": \"5246\"," +
        // "\"riverchief\": \"刘德辉\"," +
        // "\"pac\":\"5110\"," +
        // "\"riverchieflevel\": \"05\"," +
        // "\"objtype\":\"111\"," +
        // "\"sid\":\"1673\"," +
        // "\"riverbasin\": \"04\"," +
        // "\"river\":\"石桥井河新店镇段(村级)\"," +
        // "\"riversection\":\"石桥井河新店镇段(村级)\"," +
        // "\"patrolriverstartdate\":\"2020-11-03 15:54:23.0\"," +
        // "\"patrolriverEnddate\":\"2020-11-03 15:55:26.67\"," +
        // "\"toolObjectId\":\"102082\"," +
        // "\"toolClassSign\":\"102082\"," +
        // "\"riverbasinname\":\"石桥井河新店镇段(村级)\"}
        BaseDSync baseDSync = new BaseDSync();
        baseDSync.accountsHeader = "Authorization";
        baseDSync.accountsServer = "http://182.151.44.90:5010/framework/api/Accounts/auth";
        baseDSync.accountsAuthSecretKey = "ru$zmp!Bzoxa#yXArziNreH%7FBN8F";
        baseDSync.accountsAuthId = "13568020358";
        baseDSync.accountsAuthKey = "000000";
        Response response = baseDSync.syncPost(CommonConstant.TASK_推送_巡查任务, dataJson, "http://182.151.44.90:5010/op/api/erInspection/record");
        System.out.println(response);
    }
}
